package helper

import (
	"fmt"
	"reflect"

	"gitee.com/hp-huiw/my-go-core/config"
	"gitee.com/hp-huiw/my-go-core/util"
)

const successStatus string = "1"

type AMapHelper interface {
	QueryByCoordinate(latitude float64, longitude float64) map[string]any
	QueryPoiByKeywords(keywords string) []any
}

func NewAMapHelper() AMapHelper {
	return amapHelper{}
}

func (amapHelper amapHelper) QueryByCoordinate(latitude float64, longitude float64) map[string]any {
	amapConfig := config.ConfigLoader.GetAppConfig().AMap

	// Prepares route.
	route := fmt.Sprintf("%vv3/geocode/regeo", amapConfig.RestApiUrl)

	// Prepares get parameters.
	params := map[string]any{
		"key":      amapConfig.WebApiKey,
		"location": fmt.Sprintf("%v,%v", longitude, latitude),
	}

	// Makes request.
	response := util.NewHttpRequestHelper().Get(route, params)

	if response["status"] == successStatus {
		return map[string]any{
			"latitude":         latitude,
			"longitude":        longitude,
			"country":          amapHelper.getStringValue(response["regeocode"].(map[string]any)["addressComponent"].(map[string]any)["country"]),
			"province":         amapHelper.getStringValue(response["regeocode"].(map[string]any)["addressComponent"].(map[string]any)["province"]),
			"city":             amapHelper.getStringValue(response["regeocode"].(map[string]any)["addressComponent"].(map[string]any)["city"]),
			"district":         amapHelper.getStringValue(response["regeocode"].(map[string]any)["addressComponent"].(map[string]any)["district"]),
			"township":         amapHelper.getStringValue(response["regeocode"].(map[string]any)["addressComponent"].(map[string]any)["township"]),
			"formattedAddress": amapHelper.getStringValue(response["regeocode"].(map[string]any)["formatted_address"]),
			"adCode":           amapHelper.getStringValue(response["regeocode"].(map[string]any)["addressComponent"].(map[string]any)["adcode"]),
			"cityCode":         amapHelper.getStringValue(response["regeocode"].(map[string]any)["addressComponent"].(map[string]any)["citycode"]),
			"townCode":         amapHelper.getStringValue(response["regeocode"].(map[string]any)["addressComponent"].(map[string]any)["towncode"]),
		}
	}

	return nil
}

func (amapHelper) QueryPoiByKeywords(keywords string) []any {
	amapConfig := config.ConfigLoader.GetAppConfig().AMap

	// Prepares route.
	route := fmt.Sprintf("%vv3/place/text", amapConfig.RestApiUrl)

	// Prepares get parameters.
	params := map[string]any{
		"key":      amapConfig.WebApiKey,
		"keywords": keywords,
	}

	// Makes request.
	response := util.NewHttpRequestHelper().Get(route, params)

	if response["status"] == successStatus {
		return response["pois"].([]any)
	}

	return []any{}
}

// If coordinate is outside of China item of response will be an empty list instead of string.
// That's why we need to check on it.
func (amapHelper) getStringValue(item any) string {
	if reflect.TypeOf(item).Kind() == reflect.Slice {
		return ""
	}

	return item.(string)
}

// Container of AMapHelper functions.
type amapHelper struct{}
